from qt import *
import sys, getopt
import db
import logging
import random

class MainWindow(QMainWindow):

    def __init__(self, db, *args):
        apply(QMainWindow.__init__, (self, ) + args)
        self.setCaption("Ato - A Tool to remember")
        self.setName("main window")

        self.db = db
        self.item = None

        self.mainWidget=QWidget(self) # dummy widget to contain the
                                      # layout manager
        self.setCentralWidget(self.mainWidget)
        self.mainLayout=QVBoxLayout(self.mainWidget, 5, 5, "main")
        self.buttonLayout=QHBoxLayout(self.mainLayout, 5, "button")
        self.hintsLayout=QHBoxLayout(self.mainLayout, 5, "hints")

        self.bnGetNext=QPushButton("&Next", self.mainWidget, "get next question")
        self.connect(self.bnGetNext, SIGNAL("clicked()"),
                self.slotGetNextQuestion)

        self.bnShowHint=QPushButton("Show &Hint",
                self.mainWidget, "show hint")
        self.connect(self.bnShowHint, SIGNAL("clicked()"),
                self.slotShowHint)

        self.bnShowUp=QPushButton("Show &up",
                self.mainWidget, "give up")
        self.connect(self.bnShowUp, SIGNAL("clicked()"),
                self.slotShowUp)

        self.bnGiveUp=QPushButton("&Give up",
                self.mainWidget, "give up")
        self.connect(self.bnGiveUp, SIGNAL("clicked()"),
                self.slotGiveUp)

        self.lbQuestion=QLabel("Question",
                self.mainWidget, "Question")

        self.rbHintsGrp=QVButtonGroup("Pick your favourite",
                self.mainWidget)
        self.rbHintsGrp.hide()
        self.bnChoices = [QRadioButton('%d' % i, self.rbHintsGrp) \
                for i in range(4)]
        self.connect(self.rbHintsGrp, SIGNAL("clicked(int)"),
                self.slotHintChosen)

        self.hintsLayout.addWidget(self.rbHintsGrp)
        self.buttonLayout.addWidget(self.bnGetNext)
        self.buttonLayout.addWidget(self.bnShowHint)
        self.buttonLayout.addWidget(self.bnShowUp)
        self.buttonLayout.addWidget(self.bnGiveUp)

        self.mainLayout.addWidget(self.lbQuestion)

        self.__prepareForNext()

    def __prepareForNext(self):
        self.bnGetNext.setEnabled(True)
        self.bnGetNext.setFocus()

        self.bnShowHint.setEnabled(False)
        self.bnGiveUp.setEnabled(False)
        self.bnShowUp.setEnabled(False)

    def __prepareForAnswer(self):
        self.bnGetNext.setEnabled(False)

        self.bnShowHint.setEnabled(True)
        self.bnGiveUp.setEnabled(True)
        self.bnShowUp.setEnabled(True)

        self.bnShowUp.setFocus()

    def slotGetNextQuestion(self):
        _item = self.db.getNextItem()
        if not _item:
            return

        _question = _item.question()
        self.lbQuestion.setText(_question)
        self.item = _item
        self.__prepareForAnswer()

    def slotShowHint(self):
        if not self.item:
            return

        _rbHintsGrp = self.rbHintsGrp
        _choices = self.item.choices()

        _insert = random.randrange(len(_choices))
        self.rightchoice = _insert

        _choices.insert(_insert, self.item.answer())

        _diff = len(_choices) - len(self.bnChoices)
        if _diff > 0:
            self.bnChoices.extend([
                QRadioButton(
                    '%d' % i,
                    self.rbHintsGrp) for i in range(_diff)])

        for i in range(len(_choices)):
            self.bnChoices[i].setText(_choices[i])
            self.bnChoices[i].show()

        _rbHintsGrp.show()
        _rbHintsGrp.setFocus()

        self.bnGetNext.setEnabled(False)
        self.bnShowHint.setEnabled(False)
        self.bnGiveUp.setEnabled(False)
        self.bnShowUp.setEnabled(False)

    def slotHintChosen(self, choice):
        if choice == self.rightchoice:
            self.db.done(True, True)
        else:
            self.lbQuestion.setText('Correct answer: %s' % self.item.answer())
            self.db.done(False, True)

        for i in range(len(self.bnChoices)):
            self.bnChoices[i].setText('')
            self.bnChoices[i].hide()
            self.bnChoices[i].setChecked(False)
        self.rbHintsGrp.setChecked(False)
        self.rbHintsGrp.hide()

        self.__prepareForNext()

    def slotGiveUp(self):
        _real_answer = self.item.answer()
        self.db.done(None)
        self.lbQuestion.setText('Correct answer: %s' % self.item.answer())
        self.__prepareForNext()

    def slotShowUp(self):
        _real_answer = self.item.answer()
        _reply = QMessageBox.question(
                self.mainWidget,
                'Did you think:',
                self.item.answer(),
                QMessageBox.Yes,
                QMessageBox.No)
        if _reply == QMessageBox.Yes:
            self.db.done()
        else:
            self.db.done(False)
            self.lbQuestion.setText('Correct answer: %s' % self.item.answer())
        self.__prepareForNext()

def parseOpt():
    shortopts = 'i:t:s'
    longopts  = []

    _import = None
    _tags   = []
    _shuffle= False

    _opts = getopt.getopt(sys.argv[1:], shortopts, longopts)
    for _opt, _value in _opts[0]:
        if _opt == '-i':
            _import = _value

        if _opt == '-t':
            _tags = _value.split(',')

        if _opt == '-s':
            _shuffle = True

    _file = _opts[1][0]

    _db = db.DB.load(_file)

    if _import:
        _db.loadQnAEveryLine(_import, tags=_tags)
        _db.generateChoices()

    if _shuffle:
        _db.shuffle()

    return _db, _file

def main(args):
    logging.basicConfig(level=logging.DEBUG)
    app=QApplication(args)
    _db, _file = parseOpt()
    win=MainWindow(_db)
    win.show()
    app.connect(app, SIGNAL("lastWindowClosed()")
                , app
                , SLOT("quit()")
                )
    app.exec_loop()
    db.DB.store(_db, _file)

def opt_spew():
    """Print an insanely verbose log of everything that happens.
       Useful when debugging freezes or locks in complex code."""
    import sys
    from twisted.python import util

    sys.settrace(util.spewer)
    try:
        import threading
    except ImportError:
        return threading.settrace(util.spewer)

if __name__=="__main__":
    #opt_spew()
    main(sys.argv)
